package com.xbongbong.pro.aiassistant.service.impl;

import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.help.UserAndDepartmentHelp;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.pro.aiassistant.handle.PaasAiAssistantStrategyHandle;
import com.xbongbong.pro.aiassistant.handle.SaasAiAssistantStrategyHandle;
import com.xbongbong.pro.aiassistant.handle.WorkReportAiAssistantStrategyHandle;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.domain.entity.AiAssistantEntity;
import com.xbongbong.pro.domain.entity.AiAssistantHistoryEntity;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.history.pojo.AiAssistantHistoryPojo;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.aiassistant.service.AiAssistantStrategyService;
import com.xbongbong.pro.aiassistant.service.SmartSettingsEsService;
import com.xbongbong.pro.aiassistant.service.SsDistributeSaveService;
import com.xbongbong.pro.aiassistant.service.SsExecutorService;
import com.xbongbong.pro.aiassistant.service.SsHistoryService;
import com.xbongbong.pro.aiassistant.service.SsMessageMergeService;
import com.xbongbong.pro.smartsettings.pojo.SsExecutorPojo;
import com.xbongbong.pro.smartsettings.pojo.SsHistoryValidPojo;
import com.xbongbong.pro.smartsettings.pojo.SsMessageMergePojo;
import com.xbongbong.pro.smartsettings.pojo.dto.RunStrategyDTO;
import com.xbongbong.pro.smartsettings.pojo.dto.SmartStrategyRabbitMqDTO;
import com.xbongbong.pro.sms.pojo.SmsReceiverPojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.sys.domain.entity.UserEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Author: hongxiao
 * @date: 2019-11-20 15:18
 */
@Service("aiAssistantStrategyService")
public class AiAssistantStrategyServiceImpl implements AiAssistantStrategyService {

    private static Logger logger = LoggerFactory.getLogger(AiAssistantStrategyServiceImpl.class);

    @Resource
    private SmartSettingsEsService smartSettingsEsService;
    @Resource
    private SsHistoryService ssHistoryService;
    @Resource
    private SsExecutorService ssExecutorService;
    @Resource
    private SsMessageMergeService ssMessageMergeService;
    @Resource
    private SsDistributeSaveService ssDistributeSaveService;
    @Resource
    private UserAndDepartmentHelp userAndDepartmentHelp;
    @Resource
    private PaasAiAssistantStrategyHandle paasAiAssistantStrategyHandle;
    @Resource
    private SaasAiAssistantStrategyHandle saasAiAssistantStrategyHandle;
    @Resource
    private WorkReportAiAssistantStrategyHandle workReportAiAssistantStrategyHandle;

    @Override
    public Object aiAssistantStrategy(SmartStrategyRabbitMqDTO rabbitMqDTO, RunStrategyDTO runStrategyDTO) throws XbbException {
        // 是否为测试
        boolean isTest = false;
        // 测试返回的数据
        boolean testTriggerData = false;
        boolean testValidHistoryData = false;
        boolean testExecutor = false;
        boolean testSaveHistoryData = false;
        boolean testDistributionData = false;
        boolean noSaveDistribution = false;
        // 无数据返回提示
        StringBuilder noDataTips = new StringBuilder();
        if(Objects.nonNull(runStrategyDTO)) {
            isTest = runStrategyDTO.getIsTest();
            if(isTest) {
                testTriggerData = runStrategyDTO.getTestTriggerData();
                testValidHistoryData = runStrategyDTO.getTestValidHistoryData();
                testExecutor = runStrategyDTO.getTestExecutor();
                testSaveHistoryData = runStrategyDTO.getTestSaveHistoryData();
                testDistributionData = runStrategyDTO.getTestDistributionData();
                noSaveDistribution = runStrategyDTO.getNoSaveDistribution();

                noDataTips.append("Don't have" + I18nMessageUtil.getMessage(I18nStringConstant.AI_STRATEGY_DATA));
            }
        }

        // 工作报告不请求数据，在执行人时再做处理
        boolean hasWorkReport = false;
        for(AiAssistantEntity entity : rabbitMqDTO.getList()) {
            if (Objects.equals(XbbRefTypeEnum.WORK_REPORT.getCode(), entity.getBusinessType())) {
                hasWorkReport = true;
                break;
            }
        }


        // 1.通过es查询dataIds
        Map<Long, List<Long>> dataIdsMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        smartSettingsEsService.getDataIds(rabbitMqDTO, dataIdsMap);
        // 2.查询未失效的数据&过虑失效的数据
        AiAssistantHistoryPojo aiAssistantHistoryPojo = ssHistoryService.getTriggerNum(rabbitMqDTO, dataIdsMap);
        List<SsHistoryValidPojo> validHistoryList = aiAssistantHistoryPojo.getValidPojoList();
        Map<Long, List<Long>> waitInvalidIdsMap = aiAssistantHistoryPojo.getWaitInvalidIdsMap();
        Map<Long, List<AiAssistantHistoryEntity>> waitInvalidListMap = aiAssistantHistoryPojo.getWaitInvalidListMap();
        // 工作报告有效数据（不用判断是否失效）
        Map<Long, List<AiAssistantHistoryEntity>> workReportValidListMap = aiAssistantHistoryPojo.getWorkReportTriggerNumMap();
//        List<SsHistoryValidPojo> validHistoryList = ssHistoryService.getValidHistoryList(rabbitMqDTO, dataIdsMap, waitInvalidIdsMap, waitInvalidListMap, workReportValidListMap);
        // 无推送数据，后面操作不执行，直接返回
        if(validHistoryList.isEmpty() && !hasWorkReport) {
            return noDataTips;
        }

        // 3.处理数据是否有效(工作报告已过虑，没在waitInvalidIdsMap内)
        Map<Long, List<Long>> validDataIdsMap = smartSettingsEsService.getValidDataIds(rabbitMqDTO, waitInvalidIdsMap, waitInvalidListMap);
        // 4.重新设置有效/失效数据
        ssHistoryService.handleWaitInvalidHistory(validHistoryList, validDataIdsMap);
        // 无推送数据，后面操作不执行，直接返回
        if(validHistoryList.isEmpty() && !hasWorkReport) {
            return noDataTips;
        }

        // 5.查询需要的数据（添加/更新的数据）
        Map<Long, List<Long>> addUpdateIdsMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        validHistoryList.forEach(item -> {
            addUpdateIdsMap.put(item.getSmartSettingsId(), item.getAddAndUpdateIds());
        });
        Map<Integer, List<PaasFormDataEntityExt>> saasDataListMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<PaasFormDataEntityExt> paasDataList = new ArrayList<>();
        smartSettingsEsService.getFormDataList(rabbitMqDTO, addUpdateIdsMap, saasDataListMap, paasDataList);
        // 6.策略执行人的查询 (工作报告执行人特殊处理)
        Map<Long, SsExecutorPojo> workReportExecutorListMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<SsExecutorPojo> executorList = ssExecutorService.getExecutorList(rabbitMqDTO, validHistoryList, saasDataListMap, paasDataList, workReportExecutorListMap);

        // 删除缓存
        userAndDepartmentHelp.removeRedisForDepartment(rabbitMqDTO.getCorpid());
        userAndDepartmentHelp.removeRedisForUser(rabbitMqDTO.getCorpid());
        userAndDepartmentHelp.removeRedisForUserDepartment(rabbitMqDTO.getCorpid());

        // 7.消息的聚合
        List<SsMessageMergePojo> messageMergeList = ssMessageMergeService.getMessageMerge(rabbitMqDTO, executorList);


        // 测试使用的数据
        Map<Long, List<MessageRabbitMqDTO>> testMessageMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<Map<String, String>>> testCommunicatePlanMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<SmsReceiverPojo>> testSmsMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        // 8.数据分发（消息、短信、访客）；7.添加数据/数据失效
        try {
            ssDistributeSaveService.distributeAndSave(rabbitMqDTO, validHistoryList, saasDataListMap, paasDataList, messageMergeList, executorList,
                    workReportExecutorListMap, workReportValidListMap, isTest, testMessageMap, testCommunicatePlanMap, testSmsMap, noSaveDistribution);
        } catch (XbbException e) {
            // TODO 报错处理
            logger.error("智能助手策略执行失败", e);
        }


        if (!isTest) {
            // 添加日志
            logger.info(DateUtil.getString() + "（" +rabbitMqDTO.getCorpid() + "）" + "aiAssistantFinish");
            return noDataTips;
        }
        // 返回结果
        return testShow(rabbitMqDTO, testTriggerData, testValidHistoryData, testExecutor, testSaveHistoryData, testDistributionData,
                dataIdsMap, waitInvalidIdsMap, validHistoryList, executorList, workReportExecutorListMap, testMessageMap, testCommunicatePlanMap, testSmsMap);
    }


    @Override
    public void newAiAssistantStrategy(SmartStrategyRabbitMqDTO rabbitMqDTO, RunStrategyDTO runStrategyDTO) {
        try {
            AiAssistantEntity aiAssistantEntity = rabbitMqDTO.getAiAssistantEntity();
            if (Objects.equals(SaasMarkEnum.PAAS.getCode(), aiAssistantEntity.getSaasMark())) {
                paasAiAssistantStrategyHandle.executionStrategy(rabbitMqDTO, runStrategyDTO);
            } else {
                Integer businessType = aiAssistantEntity.getBusinessType();
                if (Objects.equals(XbbRefTypeEnum.WORK_REPORT.getCode(), businessType)) {
                    workReportAiAssistantStrategyHandle.executionStrategy(rabbitMqDTO, runStrategyDTO);
                } else {
                    saasAiAssistantStrategyHandle.executionStrategy(rabbitMqDTO, runStrategyDTO);
                }
            }
        } catch (Exception e) {
            logger.info("newAiAssistantStrategy 执行策略报错：", e);
        }
    }

    /**
     *　测试使用：回显数据
     *
     * @param rabbitMqDTO 执行策略
     * @param testTriggerData 回显es查询
     * @param testValidHistoryData 回显入库记录中的有效记录
     * @param testExecutor 回显执行人
     * @param testSaveHistoryData 回显入库数据
     * @param testDistributionData 回显消息分发
     * @param dataIdsMap es查询的数据
     * @param waitInvalidIdsMap 上次入库过虑后的有效数据
     * @param validHistoryList 上次入库的有效数据
     * @param executorList 执行人
     * @param testMessageMap 分发的消息
     * @throws
     * @return
     * @author hongxiao
     * @date 2019-12-09 22:10
     * @since
     * @version
     */
    private Object testShow(SmartStrategyRabbitMqDTO rabbitMqDTO, boolean testTriggerData, boolean testValidHistoryData,
                            boolean testExecutor, boolean testSaveHistoryData, boolean testDistributionData,
                            Map<Long, List<Long>> dataIdsMap, Map<Long, List<Long>> waitInvalidIdsMap,
                            List<SsHistoryValidPojo> validHistoryList, List<SsExecutorPojo> executorList,Map<Long, SsExecutorPojo> workReportExecutorListMap,
                            Map<Long, List<MessageRabbitMqDTO>> testMessageMap, Map<Long, List<Map<String, String>>> testCommunicatePlanMap,
                            Map<Long, List<SmsReceiverPojo>> testSmsMap) {
        // 智能助手map
        Map<Long, AiAssistantEntity> aiAssistantEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (AiAssistantEntity entity : rabbitMqDTO.getList()) {
            aiAssistantEntityMap.put(entity.getId(), entity);
        }

        // 执行人map
        Map<String, UserEntity> userMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (SsExecutorPojo pojo : executorList) {
            List<UserEntity> userList = pojo.getExecutorList();
            for (UserEntity userEntity : userList) {
                if (!userMap.containsKey(userEntity.getUserId())) {
                    userMap.put(userEntity.getUserId(), userEntity);
                }
            }
        }
        for (Map.Entry<Long, SsExecutorPojo> entry : workReportExecutorListMap.entrySet()) {
            List<UserEntity> userList = entry.getValue().getExecutorList();
            for (UserEntity userEntity : userList) {
                if (!userMap.containsKey(userEntity.getUserId())) {
                    userMap.put(userEntity.getUserId(), userEntity);
                }
            }
        }

        // 返回结果
        Map<String, Object> returnMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        returnMap.put("corpId", rabbitMqDTO.getCorpid());

        // 返回触发条件查询的数据
        if(testTriggerData) {
            Map<String, List<Long>> testTriggerDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (Map.Entry<Long, List<Long>> entry : dataIdsMap.entrySet()) {
                if (aiAssistantEntityMap.containsKey(entry.getKey())) {
                    AiAssistantEntity entity = aiAssistantEntityMap.get(entry.getKey());
                    // 智能助手名称：es查询的数据ids
                    testTriggerDataMap.put(entity.getName(), entry.getValue());
                }
            }
            returnMap.put("智能助手触发条件查询的数据", testTriggerDataMap);
        }
        // 返回历史记录中未失效的数据
        if(testValidHistoryData) {
            // 过虑前的上次有效数据
            Map<String, List<Long>> testWaitInvalidDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            // 过虑后的有效数据
            Map<String, List<Long>> testValidDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (Map.Entry<Long, List<Long>> entry : waitInvalidIdsMap.entrySet()) {
                AiAssistantEntity entity = aiAssistantEntityMap.get(entry.getKey());
                // 上次有效数据
                testWaitInvalidDataMap.put(entity.getName(), entry.getValue());
            }
            for (SsHistoryValidPojo pojo : validHistoryList) {
                AiAssistantEntity entity = aiAssistantEntityMap.get(pojo.getSmartSettingsId());
                // 过虑后的有效数据
                testValidDataMap.put(entity.getName(), pojo.getAddAndUpdateIds());
            }

            Map<String, Object> testValidHistoryDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            testValidHistoryDataMap.put("待处理数据", testWaitInvalidDataMap);
            testValidHistoryDataMap.put("入库记录", testValidDataMap);
            returnMap.put("智能助手历史数据", testValidHistoryDataMap);
        }
        // 返回执行人数据
        if(testExecutor) {

            Map<String, Object> testAiAssToDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

            for (SsExecutorPojo pojo : executorList) {

                Map<String, Object> testDataToExecutorMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

                AiAssistantEntity entity = aiAssistantEntityMap.get(pojo.getSmartSettingsId());
                List<UserEntity> executorUserList = pojo.getExecutorList();
                StringBuffer userNameBuffer = new StringBuffer();
                for (UserEntity userEntity : executorUserList) {
                    if (userNameBuffer.length() == BasicConstant.ZERO) {
                        userNameBuffer.append(userEntity.getName());
                    } else {
                        userNameBuffer.append("、" + userEntity.getName());
                    }
                }
                // 智能助手:{formId_dataId: "userName1、userName2"}
                testDataToExecutorMap.put(pojo.getFormId() + StringConstant.CROSS + pojo.getDataId(), userNameBuffer.toString());
                testAiAssToDataMap.put(entity.getName(), testDataToExecutorMap);
            }

            returnMap.put("智能助手执行人", testAiAssToDataMap);
        }
        // 返回入库记录数据
        if(testSaveHistoryData) {

        }
        // 返回分发数据
        if(testDistributionData) {
            // 消息map
            Map<String, Object> testMessageDistributionDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (Map.Entry<Long, List<MessageRabbitMqDTO>> entry : testMessageMap.entrySet()) {
                AiAssistantEntity entity = aiAssistantEntityMap.get(entry.getKey());

                StringBuffer userNameBuffer = new StringBuffer();
                for (MessageRabbitMqDTO messageRabbitMqDTO : entry.getValue()) {
                    String userId = messageRabbitMqDTO.getUserIds().get(0);
                    UserEntity userEntity = userMap.get(userId);
                    if (userNameBuffer.length() == BasicConstant.ZERO) {
                        userNameBuffer.append(userEntity.getName());
                    } else {
                        userNameBuffer.append("、" + userEntity.getName());
                    }
                }
                testMessageDistributionDataMap.put(entity.getName(), userNameBuffer.toString());
            }
            returnMap.put("消息分发", testMessageDistributionDataMap);

            // 短信map
            Map<String, Object> testSmsDistributionDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (Map.Entry<Long, List<SmsReceiverPojo>> entry : testSmsMap.entrySet()) {
                AiAssistantEntity entity = aiAssistantEntityMap.get(entry.getKey());
                StringBuffer userNameBuffer = new StringBuffer();
                for (SmsReceiverPojo pojo : entry.getValue()) {
                    if (userNameBuffer.length() == BasicConstant.ZERO) {
                        userNameBuffer.append(pojo.getName());
                    } else {
                        userNameBuffer.append("、" + pojo.getName());
                    }
                }
                testSmsDistributionDataMap.put(entity.getName(), userNameBuffer.toString());
            }
            returnMap.put("短信发送", testSmsDistributionDataMap);
            // 访客map
            Map<String, Object> testCommunicatePlanDisDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (Map.Entry<Long, List<Map<String, String>>> entry : testCommunicatePlanMap.entrySet()) {
                AiAssistantEntity entity = aiAssistantEntityMap.get(entry.getKey());
                testCommunicatePlanDisDataMap.put(entity.getName(), entry.getValue());
            }
            returnMap.put("访客计划", testCommunicatePlanDisDataMap);
        }

        return returnMap;
    }
}
